#include <iostream>
#include <string>
#include <functional>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

using ws_server_t = websocketpp::server<websocketpp::config::asio>;
void http_handler(ws_server_t *wsvr, websocketpp::connection_hdl hdl)
{
    ws_server_t::connection_ptr conn = wsvr->get_con_from_hdl(hdl);
    std::cout << "body: " << conn->get_request_body() << std::endl;
    websocketpp::http::parser::request req = conn->get_request();
    std::cout <<  "method: " << req.get_method() << std::endl;
    std::cout << "uri: " << req.get_uri() << std::endl;

    std::string body = "<html><body><h1>Hello World</h1></body></html>";
    conn->set_body(conn->get_request_body());
    //conn->set_body(body);
    //conn->append_header("Content-Type", "text/html");
    conn->set_status(websocketpp::http::status_code::ok);
}
void ws_open_handler(ws_server_t *wsvr, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket 握手成功!!!\n";
}
void ws_close_handler(ws_server_t *wsvr, websocketpp::connection_hdl hdl)
{
    std::cout << "webscket 断开连接!!!\n";
}
void ws_msg_handler(ws_server_t *wsvr, websocketpp::connection_hdl hdl, ws_server_t::message_ptr msg)
{
    ws_server_t::connection_ptr conn  = wsvr->get_con_from_hdl(hdl);
    std::cout << "wsmsg: " << msg->get_payload() << std::endl;
    std::string resp = "clietn say@ " + msg->get_payload();
    conn->send(resp, websocketpp::frame::opcode::text);
}

int main()
{
    // 1. 实例化websocket server 对象
    ws_server_t wsvr;
    // 2. 设置日志不可见
    wsvr.set_access_channels(websocketpp::log::alevel::none);
    // 3. 初始化asio调度器
    wsvr.init_asio();
    wsvr.set_reuse_addr(true);
    // 4. 设置回调函数
    wsvr.set_http_handler(std::bind(http_handler, &wsvr, std::placeholders::_1));
    wsvr.set_open_handler(std::bind(ws_open_handler, &wsvr, std::placeholders::_1));
    wsvr.set_close_handler(std::bind(ws_close_handler, &wsvr, std::placeholders::_1));
    wsvr.set_message_handler(std::bind(ws_msg_handler, &wsvr, std::placeholders::_1, std::placeholders::_2));
    // 5. 监听端口
    wsvr.listen(8080);
    // 6. 获取新连接
    wsvr.start_accept();
    // 7. 启动服务器
    wsvr.run();

    return 0;
}